package admin

import (
	"ecms/middlewares"
	"ecms/models"
	"ecms/utils/converter"
	"ecms/utils/hash"
	"ecms/utils/reflects"
	"ecms/utils/repository"
	"ecms/utils/response"
	"ecms/utils/validator"
	"github.com/gin-gonic/gin"
	"time"
)

type MemberController struct{}

// Profile 用户资料接口
func (u *MemberController) Profile(ctx *gin.Context) {
	userInfo, has := middlewares.GetAdminUser(ctx)
	if !has {
		response.FailJson(ctx, "用户状态异常", nil)
		return
	}

	nowUserInfo := &models.AdminMember{}
	repo := repository.New(&models.AdminMember{})
	if noErr := repo.FindById(userInfo.Id, nowUserInfo); !noErr || nowUserInfo.Id == 0 {
		response.FailJson(ctx, "用户状态异常", nil)
		return
	}

	response.SuccessJson(ctx, "查询成功", struct {
		Username    string `json:"username"`
		Nickname    string `json:"nickname"`
		Avatar      string `json:"avatar"`
		Email       string `json:"email"`
		Mobile      string `json:"mobile"`
		Description string `json:"description"`
	}{
		Username:    nowUserInfo.Username,
		Nickname:    nowUserInfo.Nickname,
		Avatar:      nowUserInfo.Avatar,
		Email:       nowUserInfo.Email,
		Mobile:      nowUserInfo.Mobile,
		Description: nowUserInfo.Description,
	})
}

// UpdateProfile 更新用户资料接口
func (u *MemberController) UpdateProfile(ctx *gin.Context) {
	reqData := &models.AdminMember{}
	rules := validator.NewRules(
		validator.NewRule("nickname", "昵称", true, validator.TypeNoEmpty),
		validator.NewRule("avatar", "头像", true, validator.TypeLink),
		validator.NewRule("email", "邮箱", true, validator.TypeEmail),
		validator.NewRule("mobile", "手机号", true, validator.TypePhone),
		validator.NewRule("description", "个人简介", false, validator.TypeNoEmpty),
	)
	if !validator.ShouldBindFromPostForm(ctx, reqData, rules...) {
		return
	}

	userInfo, has := middlewares.GetAdminUser(ctx)
	if !has {
		response.FailJson(ctx, "用户状态异常", nil)
		return
	}

	nowUserInfo := &models.AdminMember{}
	repo := repository.New(&models.AdminMember{})
	if noErr := repo.FindById(userInfo.Id, nowUserInfo); !noErr || nowUserInfo.Id == 0 {
		response.FailJson(ctx, "用户状态异常", nil)
		return
	}

	// 更新字段
	refObj, err := reflects.NewObject(nowUserInfo)
	if err != nil {
		response.FailJson(ctx, "编辑失败, 请稍后再试", nil)
		return
	}
	fields := []string{"nickname", "avatar", "email", "mobile", "description"}
	refObj.BatchSetValueFromFields(fields, reqData)
	nowUserInfo.UpdatedAt = response.Time(time.Now().Local())

	if !repo.UpdateById(nowUserInfo.Id, nowUserInfo) {
		response.FailJson(ctx, "编辑失败, 请稍后再试", nil)
		return
	}

	response.SuccessJson(ctx, "编辑成功", nil)
}

// Index 用户列表接口
func (u *MemberController) Index(ctx *gin.Context) {
	reqData := make(map[string]string)
	rules := validator.NewRules(
		validator.NewRule("status", "状态", true, validator.TypeStatus),
		validator.NewRule("page", "分页", true, validator.TypeNumberNoneZero),
		validator.NewRule("page_size", "分页大小", true, validator.TypeNumberNoneZero),
		validator.NewRule("keyword", "搜索词", false, validator.TypeNoEmpty),
	)
	if !validator.ShouldBindMapFromPostForm(ctx, &reqData, rules...) {
		return
	}

	lists := make([]models.AdminMember, 0)
	var total int64 = 0

	repo := repository.New(&models.AdminMember{})

	query := "status = ? AND is_deleted = 0"
	args := []interface{}{reqData["status"]}
	if reqData["keyword"] != "" {
		repo.BuildSearchQuery(&query, []string{"username", "nickname", "mobile", "email"}, reqData["keyword"], &args)
	}

	if !repo.Pagination(&repository.PaginationQuery{
		Out:      &lists,
		Page:     converter.Str2Int(reqData["page"]),
		PageSize: converter.Str2Int(reqData["page_size"]),
		Query:    query,
		Count:    &total,
		Args:     args,
		Order:    "sort ASC, updated_at DESC",
	}) {
		response.FailJson(ctx, "查询失败, 请稍后再试", nil)
		return
	}

	response.SuccessJson(ctx, "查询成功", struct {
		Total int64                `json:"total"`
		Lists []models.AdminMember `json:"lists"`
	}{
		Total: total,
		Lists: lists,
	})
}

// Create 用户添加
func (u *MemberController) Create(ctx *gin.Context) {
	reqData := &models.AdminMember{
		Status:    1,
		IsDeleted: 0,
		CreatedAt: response.NowTime(),
		UpdatedAt: response.NowTime(),
	}
	rules := validator.NewRules(
		validator.NewRule("username", "用户名称", true, validator.TypeAlpha),
		validator.NewRule("nickname", "用户昵称", true, validator.TypeNoEmpty),
		validator.NewRule("avatar", "用户头像", true, validator.TypeLink),
		validator.NewRule("mobile", "联系电话", true, validator.TypePhone),
		validator.NewRule("email", "邮箱地址", true, validator.TypeEmail),
		validator.NewRule("description", "个人简介", false, validator.TypeNoEmpty),
		validator.NewRule("department", "所属部门", true, validator.TypeNumberNoneZero),
		validator.NewRule("role", "所属角色", true, validator.TypeNumberNoneZero),
		validator.NewRule("password", "登录密码", true, validator.TypePassword),
		validator.NewRule("sort", "用户排序", true, validator.TypeNumber),
	)
	if !validator.ShouldBindFromPostForm(ctx, reqData, rules...) {
		return
	}

	// 同名用户
	repo := repository.New(&models.AdminMember{})
	hasSame := &models.AdminMember{}
	if repo.Find(hasSame, "is_deleted = 0 AND username = ?", reqData.Username) && hasSame.Id != 0 {
		response.FailJson(ctx, "已存在相同用户名", nil)
		return
	}

	// 密码计算hash
	reqData.Password = hash.PasswordHash(reqData.Password)

	if !repo.Create(reqData) {
		response.FailJson(ctx, "添加失败, 请稍后再试", nil)
		return
	}

	response.SuccessJson(ctx, "添加成功", nil)
}

// Update 用户编辑
func (u *MemberController) Update(ctx *gin.Context) {
	reqData := &models.AdminMember{}
	rules := validator.NewRules(
		validator.NewRule("id", "管理员ID", true, validator.TypeNumberNoneZero),
		validator.NewRule("nickname", "用户昵称", true, validator.TypeNoEmpty),
		validator.NewRule("avatar", "用户头像", true, validator.TypeLink),
		validator.NewRule("mobile", "联系电话", true, validator.TypePhone),
		validator.NewRule("email", "邮箱地址", true, validator.TypeEmail),
		validator.NewRule("description", "个人简介", false, validator.TypeNoEmpty),
		validator.NewRule("department", "所属部门", true, validator.TypeNumberNoneZero),
		validator.NewRule("role", "所属角色", true, validator.TypeNumberNoneZero),
		validator.NewRule("password", "登录密码", false, validator.TypePassword),
		validator.NewRule("sort", "用户排序", true, validator.TypeNumber),
	)
	if !validator.ShouldBindFromPostForm(ctx, reqData, rules...) {
		return
	}

	// 检查用户状态
	repo := repository.New(&models.AdminMember{})
	hasMember := &models.AdminMember{}
	if !repo.FindById(reqData.Id, hasMember) || hasMember.Id != reqData.Id {
		response.FailJson(ctx, "管理员信息已失效", nil)
		return
	}

	// 如果更改了密码
	if reqData.Password != "" {
		reqData.Password = hash.PasswordHash(reqData.Password)
	} else {
		reqData.Password = hasMember.Password
	}

	// 更新字段
	refObj, err := reflects.NewObject(hasMember)
	if err != nil {
		response.FailJson(ctx, "编辑失败, 请稍后再试", nil)
		return
	}
	fields := []string{"nickname", "avatar", "mobile", "email", "description", "department", "role", "password", "sort"}
	refObj.BatchSetValueFromFields(fields, reqData)

	if !repo.UpdateById(reqData.Id, hasMember) {
		response.FailJson(ctx, "编辑失败, 请稍后再试", nil)
		return
	}

	response.SuccessJson(ctx, "编辑成功", nil)
}

// Delete 用户删除
func (u *MemberController) Delete(ctx *gin.Context) {
	reqData := &models.AdminMember{}
	rules := validator.NewRules(
		validator.NewRule("id", "管理员ID", true, validator.TypeNumberNoneZero),
	)
	if !validator.ShouldBindFromPostForm(ctx, reqData, rules...) {
		return
	}

	// 用户状态
	repo := repository.New(&models.AdminMember{})
	hasMember := &models.AdminMember{}
	if !repo.Find(hasMember, "is_deleted = 0 AND id = ?", reqData.Id) || hasMember.Id == 0 {
		response.FailJson(ctx, "管理员信息已失效", nil)
		return
	}

	if !repo.DeleteById(reqData.Id) {
		response.FailJson(ctx, "删除失败, 请稍后再试", nil)
		return
	}

	response.SuccessJson(ctx, "删除成功", nil)
}

// Enable 用户启用
func (u *MemberController) Enable(ctx *gin.Context) {
	reqData := &models.AdminMember{}
	rules := validator.NewRules(
		validator.NewRule("id", "管理员ID", true, validator.TypeNumberNoneZero),
	)
	if !validator.ShouldBindFromPostForm(ctx, reqData, rules...) {
		return
	}

	repo := repository.New(&models.AdminMember{})
	hasMember := &models.AdminMember{}
	if !repo.Find(hasMember, "status = 0 AND is_deleted = 0 AND id = ?", reqData.Id) || hasMember.Id == 0 {
		response.FailJson(ctx, "管理员信息已失效", nil)
		return
	}

	if !repo.EnableById(reqData.Id) {
		response.FailJson(ctx, "操作失败, 请稍后再试", nil)
		return
	}

	response.SuccessJson(ctx, "操作成功", nil)
}

// Disable 用户禁用
func (u *MemberController) Disable(ctx *gin.Context) {
	reqData := &models.AdminMember{}
	rules := validator.NewRules(
		validator.NewRule("id", "管理员ID", true, validator.TypeNumberNoneZero),
	)
	if !validator.ShouldBindFromPostForm(ctx, reqData, rules...) {
		return
	}

	repo := repository.New(&models.AdminMember{})
	hasMember := &models.AdminMember{}
	if !repo.Find(hasMember, "status = 1 AND is_deleted = 0 AND id = ?", reqData.Id) || hasMember.Id == 0 {
		response.FailJson(ctx, "管理员信息已失效", nil)
		return
	}

	if !repo.DisableById(reqData.Id) {
		response.FailJson(ctx, "操作失败, 请稍后再试", nil)
		return
	}

	response.SuccessJson(ctx, "操作成功", nil)
}
